#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <chrono>
#include <thread>
#include <set>
#include <map>
#include <sw/redis++/redis++.h>

using namespace std;
using namespace sw::redis;

// hset, hget and hgetall
void Test1(Redis& redis)
{
    redis.flushall();
    cout << "hset, hget and hgetall" << endl;

    redis.hset("key", {"f1", "111"});
    redis.hset("key", {make_pair("f2", "222"), make_pair("f3", "333")});
    map<string, string> m = {{"f4", "444"}, {"f5", "555"}};
    redis.hset("key", m.begin(), m.end());

    auto val = redis.hget("key", "f1");
    cout << val.value() << endl;

    vector<string> ret;
    auto it = back_inserter(ret);
    redis.hgetall("key", it);
    for(auto& e : ret) cout << e << " ";
    cout << endl; 
}

// hexists, hdel adn hlen
void Test2(Redis& redis)
{
    redis.flushall();
    cout << "hexists and hdel" << endl;

    redis.hset("key", {"f1", "111"});
    redis.hset("key", {make_pair("f2", "222"), make_pair("f3", "333")});
    map<string, string> m = {{"f4", "444"}, {"f5", "555"}};
    redis.hset("key", m.begin(), m.end());

    auto ret = redis.hexists("key", "f1");
    cout << ret << endl;

    redis.hdel("key", "f1");
    redis.hdel("key", {"f2", "f3"});

    ret = redis.hexists("key", "f1");
    cout << ret << endl;

    auto len = redis.hlen("key");
    cout << "len: " << len << endl;
} 

// hkeys and hvals
void Test3(Redis& redis)
{
    redis.flushall();
    cout << "hkeys and hvals" << endl;   

    redis.hset("key", {"f1", "111"});
    redis.hset("key", {make_pair("f2", "222"), make_pair("f3", "333")});
    map<string, string> m = {{"f4", "444"}, {"f5", "555"}};
    redis.hset("key", m.begin(), m.end());

    vector<string> ret;
    auto it = back_inserter(ret);
    redis.hkeys("key", it);
    for(auto& e : ret) cout << e << " ";
    cout << endl;

    ret.clear();
    it = back_inserter(ret);
    redis.hvals("key", it);
    for(auto& e : ret) cout << e << " ";
    cout << endl;
}

// hmset and hmget
void Test4(Redis& redis)
{
    redis.flushall();
    cout << "hmset and hmget" << endl;

    redis.hmset("key", {
        make_pair("f1", "111"),
        make_pair("f2", "222"),
        make_pair("f3", "333")
    });

    vector<pair<string, string>> pairs = {
        {"f4", "444"},
        {"f5", "555"},
        {"f6", "666"}
    };
    redis.hset("key", pairs.begin(), pairs.end());

    vector<string> values;
    auto it = back_inserter(values);
    redis.hmget("key", {"f1", "f2", "f3", "f4", "f5", "f6"}, it);
    for(auto& e : values) cout << e << " ";
    cout << endl;
}

int main()
{
    sw::redis::Redis redis("tcp://127.0.0.1:6379");
    // Test1(redis);
    // Test2(redis);
    // Test3(redis);
    Test4(redis);

    return 0;
}